package cn.javabb.project.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.javabb.common.constant.GenConstants;
import cn.javabb.framework.config.DataSourceConfig;
import cn.javabb.framework.model.GenModel;
import cn.javabb.project.entity.GenTable;
import cn.javabb.project.entity.GenTableColumn;
import cn.javabb.project.entity.SysConfig;
import cn.javabb.project.entity.SysDataSource;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RegExUtils;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @desc:
 * @author: javabb (javabob(a)163.com)
 * @create: 2021/04/25 16:33
 */
@Slf4j
public class GenUtil {

    public static DataSourceConfig getDataSourceConfig(SysDataSource sdc) {
        if (ObjectUtil.isNull(sdc)) {
            throw new RuntimeException("数据源不存在");
        }
        return DataSourceConfig.builder()
                .url(sdc.getUrl())
                .driverName(sdc.getDriverName())
                .username(sdc.getUsername())
                .password(sdc.getPassword())
                .build();
    }

    /**
     * 表名转换成Java类名
     * sys_user -> User
     *
     * @param tableName
     * @param removePrefix 去掉表前缀
     * @return
     */
    public static String convertClassName(String tableName, String removePrefix) {
        if (StrUtil.isNotEmpty(removePrefix)) {
            String[] searchList = StrUtil.split(removePrefix, ",");
            for (String pre : searchList) {
                tableName = StrUtil.removePrefix(tableName, pre);
            }
        }
        return StrUtil.upperFirst(StrUtil.toCamelCase(tableName));
    }

    /**
     * 表名转换成Java类名
     * sys_user -> User
     *
     * @param tableName
     * @param removePrefixs 去掉表前缀
     * @return
     */
    public static String convertClassName(String tableName, List<String> removePrefixs) {
        return StrUtil.upperFirst(StrUtil.toCamelCase(removePrefixs(tableName, removePrefixs)));
    }

    /**
     * 表名转换成Java类名
     * sys_user -> User
     *
     * @param tableName
     * @param removePrefixs 去掉表前缀
     * @return
     */
    public static String removePrefixs(String tableName, List<String> removePrefixs) {
        if (CollUtil.isEmpty(removePrefixs)) {
            return tableName;
        }
        for (String pre : removePrefixs) {
            tableName = StrUtil.removePrefix(tableName, pre);
        }
        return tableName;
    }

    /**
     * 获取模块名
     *
     * @param packageName 包名
     * @return 模块名
     */
    public static String getModuleName(String packageName) {
        int lastIndex = packageName.lastIndexOf(".");
        int nameLength = packageName.length();
        String moduleName = StrUtil.sub(packageName, lastIndex + 1, nameLength);
        return moduleName;
    }

    /**
     * 获取业务名
     *
     * @param tableName 表名
     * @return 业务名
     */
    public static String getBusinessName(String tableName) {
        int lastIndex = tableName.lastIndexOf("_");
        int nameLength = tableName.length();
        String businessName = StrUtil.sub(tableName, lastIndex + 1, nameLength);
        return businessName;
    }


    /**
     * 批量替换前缀
     *
     * @param replacementm 替换值
     * @param searchList   替换列表
     * @return
     */
    public static String replaceFirst(String replacementm, String[] searchList) {
        String text = replacementm;
        for (String searchString : searchList) {
            if (replacementm.startsWith(searchString)) {
                text = replacementm.replaceFirst(searchString, "");
                break;
            }
        }
        return text;
    }

    /**
     * 关键字替换
     *
     * @param text 需要被替换的名字
     */
    public static String replaceText(String text) {
        if (StrUtil.isBlank(text)) {
            return "";
        }
        return RegExUtils.replaceAll(text, "(?:表|javabb)", "").replaceAll("\r\n", "\t");
    }

    /**
     * 获取数据库类型字段
     *
     * @param columnType 列类型
     * @return 截取后的列类型
     */
    public static String getDbType(String columnType) {
        if (StrUtil.isNotBlank(columnType) && columnType.indexOf("(") > 0) {
            return StrUtil.subBefore(columnType, "(", true);
        } else {
            return columnType;
        }
    }

    /**
     * 获取字段长度
     *
     * @param columnType 列类型
     * @return 截取后的列类型
     */
    public static Integer getColumnLength(String columnType) {
        if (StrUtil.isNotBlank(columnType) && columnType.indexOf("(") > 0) {
            String length = StrUtil.subBetween(columnType, "(", ")");
            return Integer.valueOf(length);
        } else {
            return 0;
        }
    }

    /**
     * 校验数组是否包含指定值
     *
     * @param arr         数组
     * @param targetValue 值
     * @return 是否包含
     */
    public static boolean arraysContains(String[] arr, String targetValue) {
        return Arrays.asList(arr).contains(targetValue);
    }


    /**
     * @param tables
     * @return
     */
    public static List<GenModel> getGenModule(List<String> tables, List<String> tablePrefix) {
        List<GenModel> moduleList = new ArrayList<>();
        Map<String, List<String>> moduleMap = new HashMap<>();
        Set<String> tableSet = new HashSet<>();

        for (String tableName : tables) {
            for (String prefix : tablePrefix) {
                if (tableName.startsWith(prefix)) {
                    String moduleName = prefix.endsWith("_") ? StrUtil.subBefore(prefix, "_", true) : prefix;
                    if (moduleMap.containsKey(moduleName)) {
                        List<String> tempList = moduleMap.get(moduleName);
                        tempList.add(tableName);
                        moduleMap.put(moduleName, tempList);
                    } else {
                        moduleMap.put(moduleName, CollUtil.toList(tableName));
                    }
                    tableSet.add(tableName);
                    break;
                }
            }
        }
        List<String> otherTable = new ArrayList<>();
        for (String tableName : tables) {
            if (!tableSet.contains(tableName)) {
                otherTable.add(tableName);
            }
        }
        if (CollUtil.isNotEmpty(otherTable)) {
            GenModel model = new GenModel();
            model.setModelName("");
            model.setTables(otherTable);
            moduleList.add(model);
        }
        for (String key : moduleMap.keySet()) {
            GenModel model = new GenModel();
            model.setModelName(key);
            model.setTables(moduleMap.get(key));
            model.setPrefix(tablePrefix);
            moduleList.add(model);
        }
        return moduleList;
    }

    public static void open(String outDir) {
        if (StrUtil.isNotEmpty(outDir)) {
            try {
                String osName = System.getProperty("os.name");
                if (osName != null) {
                    if (osName.contains("Mac")) {
                        Runtime.getRuntime().exec("open " + outDir);
                    } else if (osName.contains("Windows")) {
                        Runtime.getRuntime().exec("cmd /c start " + outDir);
                    } else {
                        log.debug("文件输出目录:" + outDir);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        List<String> tables = CollUtil.toList("sys_user", "sys_role", "sys_user_role", "biz_post");
        List<String> tablePrefix = CollUtil.toList("sys_", "biz_");
        List<GenModel> module = getGenModule(tables, tablePrefix);
        module.stream().forEach(t -> System.out.println(t));

        //System.out.println(StrUtil.sub("biz_common", 0, "biz_common".indexOf("_")));
    }

}
